#include "StdAfx.h"
#include "QvCrypto.h"

QvCrypto::QvCrypto()
{
    m_hHash = 0;
}

QvCrypto::~QvCrypto()
{
    if(m_hHash)
    {
        CryptDestroyHash(m_hHash);
    }
}

QvBoolean QvCrypto::Init(QvUInt32 nHashIdentify)
{
    if(m_hHash)
    {
        CryptDestroyHash(m_hHash);
        m_hHash = 0;
    }
    CryptCreateHash(g_hCryptoProvider, nHashIdentify, 0, 0, &m_hHash);
    if(m_hHash)
    {
        return TRUE;
    }
    //else
    //{
    //    HCRYPTKEY key = 0;
    //    CryptGenKey(g_hCryptoProvider, nHashIdentify, CRYPT_ARCHIVABLE, &key);
    //    if(key)
    //    {
    //        CryptCreateHash(g_hCryptoProvider, nHashIdentify, key, 0, &m_hHash);
    //        CryptDestroyKey(key);
    //        if(m_hHash)
    //        {
    //            return TRUE;
    //        }
    //    }
    //}
    return FALSE;
}

QvBoolean QvCrypto::Update(QvUByte *input, QvInt32 nInputLen)
{
    if(m_hHash && (nInputLen > 0) && CryptHashData(m_hHash, input, nInputLen, 0))
    {
        return TRUE;
    }
    return FALSE;
}

QvString QvCrypto::Final()
{
    QvBoolean bSuccess = FALSE;
    DWORD dwLength = 256;
    QvUByte theResult[256] = {0};
    if(m_hHash && CryptGetHashParam(m_hHash, HP_HASHVAL, theResult, &dwLength, 0))
    {
        CryptDestroyHash(m_hHash);
        m_hHash = 0;
        QvString strResult;
        for (DWORD i = 0; i < dwLength; i++)
        {
            strResult.AppendFormat(L"%02x", theResult[i]);
        }
        return QvString(strResult);
    }
    if(m_hHash)
    {
        CryptDestroyHash(m_hHash);
        m_hHash = 0;
    }
    return QvString();
}


